﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
using System.IO;
using FCModel;
using System.Data;
using FCDAL;
using System.Globalization;

namespace FCBLL
{
    public class HGSAResonanceBLL
    {

        public static List<TestResult> ReadTestResult(List<string> listTestResult)
        {
            List<TestResult> listTR = new List<TestResult>();

            foreach (string testresult in listTestResult)
            {
                string HSANo = "";
                string HeadPos = "";
                string[] arrtrfilename = testresult.Split('\\');
                string[] arrFile = arrtrfilename[arrtrfilename.Length - 1].Split(new char[] { 'H', 'h' });
                HSANo = Convert.ToInt32(arrFile[0].Replace("B", "").Replace("b", "")).ToString();
                HeadPos = Convert.ToInt32(arrFile[1]).ToString();
                List<string> listtmpTestResult = File.ReadAllLines(testresult).ToList();
                foreach (string tmptestreslut in listtmpTestResult)
                {
                    string[] arrtr = tmptestreslut.Split('\t');
                    TestResult tr = new TestResult();
                    tr.HSANo = HSANo;
                    tr.HeadPos = HeadPos;
                    tr.X = arrtr[0];
                    tr.Y1 = arrtr[1];
                    tr.Y2 = arrtr[2];
                    listTR.Add(tr);
                }
            }
            return listTR;
        }

        public static List<SummaryData> ReadSummaryData(List<string> listSummaryData) 
        {
            List<SummaryData> listHR = new List<SummaryData>();
            //if (listSummaryData[2].Split(',')[2].ToString().ToLower().Contains("shenzhen"))
            //{
            //     seq = checkOrCreateName("C");
            //}
            //if (listSummaryData[2].Split(',')[2].ToString().ToLower().Contains("suzhou"))
            //{
            //     seq = checkOrCreateName("X");
            //}
            foreach (string tr in listSummaryData)
            {
                if (tr.StartsWith("PRODUCT_FAMILY,NUM_HEAD_CONFIG,SITE,EVENT_DATE,BUILD_TYPE", StringComparison.OrdinalIgnoreCase)) continue;

                string[] arrtr = tr.Split(',');
                SummaryData hr = new SummaryData();
                #region set value
                hr.PRODUCT_FAMILY = arrtr[0];
                hr.NUM_HEAD_CONFIG = arrtr[1];
                hr.SITE = arrtr[2];
                hr.EVENT_DATE = Convert.ToDateTime(arrtr[3]).ToString("yyyy/MM/dd HH:mm:ss");
                hr.BUILD_TYPE = arrtr[4];
                hr.UNIT_TYPE = arrtr[5];
                hr.ARM_VENDOR = arrtr[6];
                hr.BEARING_VENDOR = arrtr[7];
                hr.TGA_VENDOR = arrtr[8];
                hr.SERIAL_NUM = cutString(arrtr[9], 9);
                hr.HSA_No = arrtr[10];
                hr.TEST_STATUS = arrtr[11];
                hr.GID = arrtr[12];
                hr.Head = arrtr[13];
                hr.TEST_TYPE = arrtr[14];
                hr.F1FREQ = arrtr[15];
                hr.F1MAG = arrtr[16];
                hr.F2FREQ = arrtr[17];
                hr.F2MAG = arrtr[18];
                hr.F3FREQ = arrtr[19];
                hr.F3MAG = arrtr[20];
                hr.F4FREQ = arrtr[21];
                hr.F4MAG = arrtr[22];
                hr.F5FREQ = arrtr[23];
                hr.F5MAG = arrtr[24];
                hr.F6FREQ = arrtr[25];
                hr.F6MAG = arrtr[26];
                hr.F7FREQ = arrtr[27];
                hr.F7MAG = arrtr[28];
                hr.F8FREQ = arrtr[29];
                hr.F8MAG = arrtr[30];
                hr.F9FREQ = arrtr[31];
                hr.F9MAG = arrtr[32];
                hr.F10FREQ = arrtr[33];
                hr.F10MAG = arrtr[34];
                hr.F11FREQ = arrtr[35];
                hr.F11MAG = arrtr[36];
                hr.F12FREQ = arrtr[37];
                hr.F12MAG = arrtr[38];
                hr.F13FREQ = arrtr[39];
                hr.F13MAG = arrtr[40];
                hr.F14FREQ = arrtr[41];
                hr.F14MAG = arrtr[42];
                hr.F15FREQ = arrtr[43];
                hr.F15MAG = arrtr[44];
                #endregion
                listHR.Add(hr);
            }
            return listHR;
        }

        /// <summary>
        /// 获取zip压缩包的文件名称
        /// </summary>
        /// <returns></returns>
        public static string getZipName(string loc,string dataType = "zip") 
        {
            return loc + DateTime.Now.ToString("ddMMyyyyHH") + getSeq(loc, dataType) + ".zip" ;
        }

        /// <summary>
        /// 获取SummaryData的文件全名
        /// </summary>
        /// <param name="path">文件路径</param>
        /// <param name="siteCode">厂别</param>
        /// <param name="dataType">数据类型</param>
        /// <returns>SummaryData的文件全名</returns>
        public static string getSummaryDataFileName(string path,string siteCode, string dataType)
        {
            string SummaryDataFileName = checkOrCreateName(siteCode, dataType);

            return path + siteCode + "U5" + SummaryDataFileName  + ".tdf";
        }
        /// <summary>
        /// 获取RAWData的文件全名
        /// </summary>
        /// <param name="path">文件路径</param>
        /// <param name="siteCode">厂别</param>
        /// <param name="dataType">数据类型</param>
        /// <returns></returns>
        public static string getRawDataFileFullName(string path, string siteCode, string dataType)
        {
            string SummaryDataFileName = checkOrCreateName(siteCode, dataType);

            return path + siteCode + "U4" + SummaryDataFileName + ".tdf";
        }

        public static string readOCRSeq(string siteCode, string ddMMyyyyHH, string dataType) 
        {
            rt_FileName_Rec FN = new BaseRepositoryBLL<rt_FileName_Rec>()
                    .LoadEntities(p => p.SiteCode.Equals(siteCode, StringComparison.OrdinalIgnoreCase)
                        && p.Date.Equals(DateTime.Now.ToString("ddMMyyyyHH"), StringComparison.OrdinalIgnoreCase)
                        && p.dataType.Equals(dataType, StringComparison.OrdinalIgnoreCase)).FirstOrDefault<rt_FileName_Rec>();

            return FN.seqNo.ToString("00");
        }

        public static string getSeq(string siteCode, string dataType) 
        {
            rt_FileName_Rec FN = new BaseRepositoryBLL<rt_FileName_Rec>()
                    .LoadEntities(p => p.SiteCode.Equals(siteCode, StringComparison.OrdinalIgnoreCase)
                        && p.Date.Equals(DateTime.Now.ToString("ddMMyyyyHH"), StringComparison.OrdinalIgnoreCase)
                        && p.dataType.Equals(dataType, StringComparison.OrdinalIgnoreCase)).FirstOrDefault<rt_FileName_Rec>();
            if (FN != null && dataType.ToUpper()!="OCR")
            {
                FN.seqNo++;
                new BaseRepositoryBLL<rt_FileName_Rec>().UpdateEntities(FN);
            }
            else if (FN != null && dataType.ToUpper() == "OCR") //存在并且是OCR
            {
                FN.seqNo--;
                new BaseRepositoryBLL<rt_FileName_Rec>().UpdateEntities(FN);
            }
            else 
            {
                FN = new rt_FileName_Rec();
                FN.SiteCode = siteCode;
                FN.Date = DateTime.Now.ToString("ddMMyyyyHH");
                FN.dataType = dataType;
                if (dataType.ToUpper() != "OCR")
                {
                    FN.seqNo = 1;
                }
                if (dataType.ToUpper() == "OCR")
                {
                    FN.seqNo = 89;
                }
                new BaseRepositoryBLL<rt_FileName_Rec>().AddEntities(FN);
            }
            return FN.seqNo.ToString("00");
        }

        public static string checkOrCreateName(string siteCode,string dataType)
        {
            rt_FileName_Rec FN = new BaseRepositoryBLL<rt_FileName_Rec>()
                    .LoadEntities(p => p.SiteCode.Equals(siteCode, StringComparison.OrdinalIgnoreCase)
                        && p.Date.Equals(DateTime.Now.ToString("yyMMdd"), StringComparison.OrdinalIgnoreCase)
                        && p.dataType.Equals(dataType,StringComparison.OrdinalIgnoreCase)).FirstOrDefault<rt_FileName_Rec>();
            if (FN !=null) 
            {
                FN.seqNo++;
                new BaseRepositoryBLL<rt_FileName_Rec>().UpdateEntities(FN);
            }
            else 
            {
                FN = new rt_FileName_Rec();
                FN.SiteCode = siteCode;
                FN.Date = DateTime.Now.ToString("yyMMdd");
                FN.dataType = dataType;
                FN.seqNo = 1;
                new BaseRepositoryBLL<rt_FileName_Rec>().AddEntities(FN);
            }
            return FN.Date+ FN.seqNo.ToString("0000");
        }

        public static List<string> MakeRawDataTDFByList(string path, string siteCode, List<RawData> RawDataList)
        {
            List<string> RawDataTDFFileNames = new List<string>();
            int num = 5000;
            int total = (int)Math.Ceiling(Math.Round((decimal)RawDataList.Count / num, 10));

            try
            {
                for (int i = 0; i < total; i++)
                {
                    List<RawData> RawData = new List<RawData>();
                    for (int j = 0; j < Math.Min(RawDataList.Count - num * i, num); j++)
                    {
                        RawData.Add(RawDataList[num * i + j]);
                    }
                    //获取文件名称
                    string filename = getRawDataFileFullName(path, siteCode, "RAW");
                    //生成5000行数据
                    MakeRawDataTDF(filename, RawData);
                    //生成的文件加入DownLoadlist
                    RawDataTDFFileNames.Add(filename);
                }

                return RawDataTDFFileNames;
            }
            catch
            {
                throw;
            }
        }

        /// <summary>
        /// 写RawData文件
        /// </summary>
        /// <param name="filename"></param>
        /// <param name="RawData"></param>
        /// <returns></returns>
        public static bool MakeRawDataTDF(string filename, List<RawData> RawData)
        {
            string Head = "SERIAL_NUM,HEAD_POSITION,EVENT_DATE,X,Y1,Y2,TEST_STATUS,PRODUCT_NAME,GID,BEARING_VENDOR,TGA_VENDOR,NUM_HEAD_CONFIG,SITE,ARM_VENDOR,TEST_TYPE,BUILD_TYPE,UNIT_TYPE";
            string HeadField = Head;
            string[] arrHead = Head.Split(',');
            string[] arrHeadField = HeadField.Split(',');
            bool brlt = false;
            using (StreamWriter sw = new StreamWriter(filename))
            {
                sw.Write(GetDataTitle(arrHead));
                sw.Write("\n");
                foreach (RawData tr in RawData)
                {
                    sw.Write(GetDataValue(arrHeadField, tr));
                    sw.Write("\n");
                }
                sw.Close();
            }
            return brlt;
        }
        /// <summary>
        /// 截取字符串
        /// </summary>
        /// <param name="oldString">原来的字符</param>
        /// <param name="bit">截取位数</param>
        /// <returns>返回截取后的字符串</returns>
        public static string cutString(string oldString,int bit)
        {
            if (oldString.Length < bit) return oldString;
            else 
            {
                return oldString.Substring(0, bit);
            }
        }
        /// <summary>
        /// 写SummaryData文件
        /// </summary>
        /// <param name="filename"></param>
        /// <param name="listHR"></param>
        /// <returns></returns>
        /// 
        public static bool MakeSummaryDataTDF(string filename, List<SummaryData> listHR)
        {
            string Head = "PRODUCT_FAMILY,NUM_HEAD_CONFIG,SITE,EVENT_DATE,BUILD_TYPE,UNIT_TYPE,ARM_VENDOR,BEARING_VENDOR,TGA_VENDOR,SERIAL_NUM,HEAD_POSITION,TEST_TYPE,F1FREQ,F1MAG,F2FREQ,F2MAG,F3FREQ,F3MAG,F4FREQ,F4MAG,F5FREQ,F5MAG,F6FREQ,F6MAG,F7FREQ,F7MAG,F8FREQ,F8MAG,F9FREQ,F9MAG,F10FREQ,F10MAG,F11FREQ,F11MAG,F12FREQ,F12MAG,F13FREQ,F13MAG,F14FREQ,F14MAG,F15FREQ,F15MAG";
            string HeadField = "PRODUCT_FAMILY,NUM_HEAD_CONFIG,SITE,EVENT_DATE,BUILD_TYPE,UNIT_TYPE,ARM_VENDOR,BEARING_VENDOR,TGA_VENDOR,SERIAL_NUM,HEAD,TEST_TYPE,F1FREQ,F1MAG,F2FREQ,F2MAG,F3FREQ,F3MAG,F4FREQ,F4MAG,F5FREQ,F5MAG,F6FREQ,F6MAG,F7FREQ,F7MAG,F8FREQ,F8MAG,F9FREQ,F9MAG,F10FREQ,F10MAG,F11FREQ,F11MAG,F12FREQ,F12MAG,F13FREQ,F13MAG,F14FREQ,F14MAG,F15FREQ,F15MAG";

            string[] arrHead= Head.Split(',');
            string[] arrHeadField =HeadField.Split(',');

            bool brlt = false;
            using (StreamWriter sw = new StreamWriter(filename))
            {
                sw.Write(GetDataTitle(arrHead));
                sw.Write("\n");
                foreach (SummaryData tr in listHR)
                {
                    sw.Write(GetDataValue(arrHeadField, tr));
                    sw.Write("\n");
                }
                sw.Close();
            }
            return brlt;
        }

        /// <summary>
        /// 删除文件和文件夹
        /// </summary>
        /// <param name="filePath"></param>
        public static void DeleteFolder(string dir)
        {
            foreach (string d in Directory.GetFileSystemEntries(dir))
            {
                if (File.Exists(d))
                {
                    FileInfo fi = new FileInfo(d);
                    if (fi.Attributes.ToString().IndexOf("ReadOnly") != -1)
                        fi.Attributes = FileAttributes.Normal;
                    File.Delete(d);//直接删除其中的文件   
                }
                else
                    DeleteFolder(d);//递归删除子文件夹   
            }
            Directory.Delete(dir);//删除已空文件夹   
        }   
    
        /// <summary>
        /// 
        /// </summary>
        /// <param name="arrHead"></param>
        /// <returns></returns>
        private static string GetDataTitle(string[] arrHead)
        {
            string s = "";
            for (int i = 0; i < arrHead.Length; i++)
            {
                if (s != "") s += ",";
                s += "\"" + arrHead[i] + "\"";
            }
            return s;
        }

        public static string GetDataValue(string[] arrHeadField, RawData tr)
        {
            string s = "";

            foreach (string field in arrHeadField)
            {
                FieldInfo[] arrfi = tr.GetType().GetFields(BindingFlags.Instance |
                   BindingFlags.Static |
                   BindingFlags.NonPublic |
                   BindingFlags.Public);
                FieldInfo fi = arrfi.Where(p => p.Name.Equals(field, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
                string value = "";
                if (fi.GetValue(tr) != System.DBNull.Value)
                {
                    value = fi.GetValue(tr).ToString();
                }
                //string value = tr.GetType().GetField(field).GetValue(tr).ToString() ;
                if (s != "") s += ",";
                if (value == "")
                {
                    s += "\"\"";
                }
                else
                {
                    s += "\"" + value.Trim() + "\"";
                }
            }
            return s;
        }

        public static string GetDataValue(string[] arrHeadField, SummaryData tr)
        {
            string s = "";

            foreach (string field in arrHeadField)
            {
                FieldInfo[] arrfi = tr.GetType().GetFields(BindingFlags.Instance |
                       BindingFlags.Static |
                       BindingFlags.NonPublic |
                       BindingFlags.Public);
                FieldInfo fi = arrfi.Where(p => p.Name.Equals(field, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
                string value = "";
                if (fi.GetValue(tr) != System.DBNull.Value)
                {
                    value = fi.GetValue(tr).ToString();
                }
                //typeof(类名).GetField(字段名，BindingFlags标识).GetValue(对象实例变量);
                //string value = typeof(SummaryData).GetField(field, BindingFlags.Instance | BindingFlags.Public).GetValue(tr).ToString();
                if (s != "") s += ",";
                if (value == "")
                {
                    s += "\"\"";
                }
                else
                {
                    s += "\"" + value.Trim() + "\"";
                }
            }
            return s;
        }

        //根据文件获取需要生成的文件类型
        public static List<RawData> getRawDataByFile(List<SummaryData> listHR, List<TestResult> listTR)
        {
            return (from hr in listHR
                    join tr in listTR
                    on new { A = hr.HSA_No, B = hr.Head } equals new { A = tr.HSANo, B = tr.HeadPos }
                    select new RawData
                    {
                        SERIAL_NUM = hr.SERIAL_NUM,
                        HEAD_POSITION = hr.Head,
                        EVENT_DATE =Convert.ToDateTime( hr.EVENT_DATE).ToString("yyyy/MM/dd HH:mm:ss"),
                        X = tr.X,
                        Y1 = tr.Y1,
                        Y2 = tr.Y2,
                        TEST_STATUS = hr.TEST_STATUS,
                        GID = hr.GID,
                        PRODUCT_NAME = hr.PRODUCT_FAMILY,
                        BEARING_VENDOR = hr.BEARING_VENDOR,
                        TGA_VENDOR = hr.TGA_VENDOR,
                        NUM_HEAD_CONFIG = hr.NUM_HEAD_CONFIG,
                        SITE = hr.SITE,
                        ARM_VENDOR = hr.ARM_VENDOR,
                        TEST_TYPE = hr.TEST_TYPE,
                        BUILD_TYPE = hr.BUILD_TYPE,
                        UNIT_TYPE = hr.UNIT_TYPE
                    }).ToList<RawData>();
        }

        public static string BuildOcrData(string SiteCode, string Dir, List<SummaryData> listHR, DateTime dtNow)
        {
            string DBConnStr = string.Empty;
            string OcrTDFFileName = Dir + "OCR" + dtNow.ToString("ddMMyyyyHH")
                + getSeq(SiteCode, "OCR") + ".TDF";
            DataTable dtResult = new OcrDAL().GetOcrData(SiteCode,
                string.Join(",", listHR.Select(p => p.SERIAL_NUM).Distinct().ToArray()));

            //dtResult = dtResult.AsEnumerable().OrderBy(o => o.Field<string>("HSA_SERIAL_NUM")).OrderBy(o => o.Field<int>("HD_POSITION")).CopyToDataTable();
           
            DataView dv = dtResult.DefaultView;
            dv.Sort = "HSA_SERIAL_NUM asc,HD_POSITION asc";

            dtResult = dv.ToTable();

            TestDataToFile(dtResult, OcrTDFFileName);
            return OcrTDFFileName;
        }

        private static void TestDataToFile(DataTable dt, string FileName)
        {
            if (dt.Rows.Count == 0) 
            {
                DataRow dr = dt.NewRow();
                dt.Rows.Add(dr);
            }
            StreamWriter sw = new StreamWriter(FileName);
            sw.WriteLine(GetDataTitle(dt.Rows[0]));
            foreach (DataRow dr in dt.Rows)
            {
                sw.WriteLine(GetDataValue(dr));
            }
            sw.Close();
        }

        private static string GetDataTitle(DataRow dr)
        {
            string s = "";
            for (int i = 0; i < dr.Table.Columns.Count; i++)
            {
                if (s != "") s += ",";
                s += "\"" + dr.Table.Columns[i].ColumnName + "\"";
            }
            return s;
        }

        private static string GetDataValue(DataRow dr)
        {
            string s = "";

            for (int i = 0; i < dr.Table.Columns.Count; i++)
            {
                if (s != "") s += ",";

                Type t = dr.Table.Columns[i].DataType;
                if (dr[i] == DBNull.Value)
                {
                    if (t == typeof(DateTime) || t == typeof(string))
                        s += "\"\"";
                    else
                        s += "";
                }
                else if (t == typeof(DateTime))
                    s += "\"" + Convert.ToDateTime(dr[i]).ToString("dd-MMM-yyyy HH:mm:ss", new CultureInfo("en-US", false)) + "\"";
                else if (t == typeof(string))
                {
                    string colName = dr.Table.Columns[i].ColumnName;
                    string colValue = dr[i].ToString().Trim();

                    if ((colName.ToUpper() == "LOT_ID") && colValue.StartsWith("SBR", StringComparison.OrdinalIgnoreCase))
                        s += "\"" + colValue.Substring(3) + "\"";
                    else
                        s += "\"" + colValue.Trim() + "\"";
                }
                else
                {
                    s += dr[i].ToString().Trim();
                }
            }

            return s;
        }   
    }
}
